package com.atguigu.c_designed.m2stucturalModel.s3Decoretor;

public class DecoretorClient {
    public static void main(String[] args) {
        // 单点黑咖啡
        Drink blackCoffee = new BlackCoffee();
        System.out.println(blackCoffee.getName()+blackCoffee.cost());
        // 黑咖啡加巧克力
        blackCoffee = new Chocolate(blackCoffee);
        System.out.println(blackCoffee.getName()+blackCoffee.cost());
        // 双份巧克力黑咖啡
        blackCoffee = new Milk(blackCoffee);
        System.out.println(blackCoffee.getName()+blackCoffee.cost());
        blackCoffee = new Milk(blackCoffee);
        System.out.println(blackCoffee.getName()+blackCoffee.cost());

    }
}


/**
 * 定义主体接口类
 */
abstract class Drink {
    public String name;
    public float price;
    //计算费用
    public abstract float cost();

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

}

/**
 * 定义具体被装饰者的接口，抽取公共方法
 */
class Coffee extends Drink{
    @Override
    public float cost() {
        return getPrice();
    }
}

/**
 * 定义具体的被装饰者
 */
class BlackCoffee extends Coffee{
    public BlackCoffee() {
        setName("黑咖啡...");
        setPrice(10f);
    }
}
class Decaf extends Coffee{
    public Decaf() {
        setName("低卡咖啡...");
        setPrice(15f);
    }
}

/**
 * 定义装饰着类，方便扩展
 */
class Decoretor extends Drink{
    // 组合其他的产品
    private Drink drink;

    public Decoretor(Drink drink) {
        this.drink = drink;
    }

    @Override
    public float cost() {
        // 自己的价钱加上引用的价钱
        return getPrice()+ drink.cost();
    }

    @Override
    public String getName() {
        return super.getName()+" "+drink.getName();
    }
}
/**
 * 具体装饰者类
 */
class Chocolate extends Decoretor{
    public Chocolate(Drink drink) {
        super(drink);
        setName("巧克力。。");
        setPrice(5f);
    }
}

class Milk extends Decoretor{
    public Milk(Drink drink) {
        super(drink);
        setName("牛奶。。");
        setPrice(2f);
    }
}